part of internal;

class Screen {
   PreElement lines;
   DivElement curs;
   TextAreaElement clip;

   int max;
   int get cnt => lines.nodes.length;

   // CONSTRUCTORS \\

   Screen (Buffer buf, State sta, DivElement cont) {
      if (buf == null) throw null_arg;
      if (sta == null) throw null_arg;
      if (cont == null) throw null_arg;
      if (cont.nodes.isNotEmpty) throw empty_div;

      // instantiate
      makeContainer(cont);
      lines = makeLines();
      curs = makeCursor();
      clip = makeClipboard();

      // insert blocks into DOM
      cont.nodes.add(lines);
      cont.nodes.add(curs);
      cont.nodes.add(clip);

      // setup max length of sliding box
      String temp = cont.style.height;
      if (!temp.endsWith('em')) throw wrong_height;
      max = int.parse(temp.substring(0, temp.length - 2));
      if (max < 7) throw small_height;

      // insert lines into DOM
      int cnt = min(buf.lineCnt, max);
      for (int i = sta.start; i < cnt; i++) {
         String temp = buf.getln(i);
         lines.nodes.add(makeLine(temp));
      }
   }

   // METHODS \\

   // patches
   void upd (int which, String what) {
      SpanElement se = lines.nodes[which];
      (se.nodes[0] as Text).data = what;
   }
   void ins (int where, String what) {
      List<Node> temp = lines.nodes;
      if (temp.length == max) temp.removeAt(temp.length - 1);
      temp.insert(where, makeLine(what));
   }
   void del (int where, String what) {
      List<Node> temp = lines.nodes;
      temp.removeAt(where);
      if (what != null) temp.insert(max - 1, makeLine(what));
   }

   // cursor repositioning
   void setl (int line) { curs.style.top = line.toString() + 'em'; }
   void setc (int char) { curs.style.left = (char / 2.0).toString() + 'em'; }

   // redraw
   void redraw (Buffer buf, State sta) {}

   // FUNCTIONS \\

   static DivElement makeCursor () {
      DivElement de = new DivElement();
      de.style
         ..width = '1px'
         ..height = '1em'
         ..backgroundColor = 'black'
         ..position = 'absolute'
         ..top = '0em'
         ..left = '0em';
      return de;
   }
   static SpanElement makeLine (String data) {
      SpanElement se = new SpanElement();
      se.nodes.add(new Text(data));
      se.style
         ..flexBasis = '1em'
         ..flexShrink = '0';
      return se;
   }
   static PreElement makeLines () {
      PreElement pe = new PreElement();
      pe.style
         ..boxSizing = 'border-box'
         ..margin = '0'
         ..display = 'flex'
         ..flexGrow = '1'
         ..flexShrink = '0'
         ..flexDirection = 'column'
         ..alignItems = 'flex-start'
         ..fontFamily = 'inherit'
         ..fontSize = 'inherit';
      return pe;
   }
   static TextAreaElement makeClipboard () {
      TextAreaElement tae = new TextAreaElement();
      tae.style
         ..position = 'absolute'
         ..opacity = '0'
         ..zIndex = '-1'
         ..top = '0'
         ..left = '0'
         ..height = '7px'
         ..width = '7px';
      return tae;
   }
   static void makeContainer (DivElement de) {
      de.style
         ..boxSizing = 'border-box'
         ..display = 'flex'
         ..overflow = 'auto'
         ..position = 'relative';
   }
}
